#include "cmode.h"
#include <map>

static std::map<std::string, std::pair<std::string, bool>> _correct_map = 
{
    {"gn",   {"ng", true}}, //lign --> ling
    {"mg",   {"ng", true}}, //homg --> hong
    {"iou",  {"iu", true}}, //qiou --> qiu
    {"uei",  {"ui", true}}, //tuei --> tui
    {"uen",  {"un", true}}  //kuen -->kun
};


int CMode::ToggleSyll(const std::string &syll, bool is_enable)
{
    auto it = _correct_map.find(syll);
    if(it == _correct_map.end())
    {
        printf("No such syll [%s] to correct\n", syll.c_str());
        return -1;
    }
    it->second.second = is_enable;
    return 0;
}

bool CMode::Input(const std::string &py)
{
    int osize = _input.size();
//todo: 处理退格：可能会影响之前纠错的内容
#if 0 
    for(auto c : py)
    {
        if('\b' == c)
        {
            if(_input.size() > 0)
            {
                _input.pop_back();
            }
        }
        else
        {
            _input.push_back(c);
        }
    }
#else
    _input += py;
#endif

    _correct.clear();
    bool corrected = false;
    while(_idx+1 < _input.size()) //至少剩余两个字符才能纠错
    {
        int len = 2;
_LABLE_CR2:
        auto syll = std::string(&_input[_idx], len);
        auto it = _correct_map.find(syll);
        if(it != _correct_map.end() && it->second.second)
        {
            auto & csyll = it->second.first; //string to correct syll
            corrected = true;
            if(_idx < osize) //需要回退错误字符
            {
                int i = _idx;
                while(i < osize && _input[i] == csyll[i-_idx])
                {
                    i++;
                }
                if(i < osize)
                {
                    _correct.append(osize - i, '\b');
                    _correct.append(csyll.c_str()+i-_idx);
                    _corrected_py.resize(_corrected_py.size()-(osize-i));
                    _corrected_py.append(csyll.c_str()+i-_idx);
                    
                }
                else //i = osize
                {
                    _correct.append(csyll.c_str()+osize-_idx);
                    _corrected_py.append(csyll.c_str()+osize-_idx);
                }
            }
            else //_idx >= osize, 仅本次输入纠错
            {
                    _correct += csyll;
                    _corrected_py += csyll;
            }
            _idx += len;
        }
        else
        {
            if(len > 2) //跳过当前字符，从下个字符重新开始匹配
            {
                if(_idx >= osize)
                {
                    _corrected_py.push_back(_input[_idx]);
                    _correct.push_back(_input[_idx]); //后续可能需要纠正
                }
                _idx++;
                len = 2;
                goto _LABLE_CR2;
            }
            else
            {
                if(_idx+2 >= _input.size())
                {
                    break;
                }
                //_idx + 2 < _input.size(), 至少还有三个字符
                len = 3;
                goto _LABLE_CR2;
            }

        }
    }
    if(_idx < _input.size())
    {
        int idx = _idx > osize ? _idx : osize;
        _correct.append(_input.c_str()+idx);
        _corrected_py.append(_input.c_str()+idx);
    }
    return corrected;
}

void CMode::Clear()
{
    _input.clear();
    _corrected_py.clear();
    _correct.clear();
    _idx = 0;    
}

